package top.jacktgq.lock.reentrantLock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import top.jacktgq.utils.LogUtils;
import top.jacktgq.utils.Sleeper;

/**
 * 
 * @Title: TestReentrantLock.java 
 * @Package top.jacktgq.lock 
 * @Description: 多线程交替输出：线程1输出 a 5次，线程2输出 b 5次，线程3输出 c 5次
 * @author CandyWall   
 * @date 2020年11月1日 下午5:49:07 
 * @version V1.0
 */
public class Demo6_3_multiThreadRunInTurn {
	public static void main(String[] args) {
		AwaitSignal awaitSignal = new AwaitSignal(5);
		Condition waitSetA = awaitSignal.newCondition();
		Condition waitSetB = awaitSignal.newCondition();
		Condition waitSetC = awaitSignal.newCondition();
		Thread t1 = new Thread(() -> {
			awaitSignal.print("a", waitSetA, waitSetB);
		}, "t1");
		Thread t2 = new Thread(() -> {
			awaitSignal.print("b", waitSetB, waitSetC);
		}, "t2");
		Thread t3 = new Thread(() -> {
			awaitSignal.print("c", waitSetC, waitSetA);
		}, "t3");
		t1.start();
		t2.start();
		t3.start();
		
		Sleeper.sleep(1);
		
		awaitSignal.lock();	//上锁
		try {
			//唤醒A休息室中的线程进行打印操作
			waitSetA.signal();
		} finally {
			awaitSignal.unlock(); //解锁
		}
	}	
}

/*
 *	输出内容	等待标记	下一个标记 
 * 	   a	  1		   2
 *     b      2        3
 *     c      3        1
 */
class AwaitSignal extends ReentrantLock {
	//循环次数
	private int loopNumber;
	public AwaitSignal(int loopNumber) {
		this.loopNumber = loopNumber;
	}
	
	/**
	 * 
	 * @param str			：打印内容
	 * @param waitSet		：进入哪一件休息室等待
	 * @param nextWaitSet	：下一个待唤醒的线程所在的休息室
	 */
	public void print(String str, Condition currentWaitSet, Condition nextWaitSet) {
		for(int i = 0; i < loopNumber; i++) {
			lock();
			try {
				try {
					currentWaitSet.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				LogUtils.log("AwaitSignal", str);
				nextWaitSet.signal();
			} finally {
				unlock();
			}
		}
	}
}
